package com.gxa.park.manager.interceptor;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.gxa.park.core.commom.ExceptionCode;
import com.gxa.park.core.exception.BusinessException;
import com.gxa.park.core.util.JWTUtil;
import com.gxa.park.manager.jwt.NeedsLogin;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @date 2022/7/19
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest,
                             HttpServletResponse httpServletResponse, Object object) throws Exception {
// 拦截用户请求,
// 判断是否需要携带token /admin/** /cart/** ,
// 通过注解加强判断: 是否需要token,
// 发现携带了注解就表示需要token
// 使用JwtUtil校验token
// 从 http 请求头中取出 token(jwt字符串)
        String token = httpServletRequest.getHeader("token");
// 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
// 获取方法对象
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
//检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(NeedsLogin.class)) {
            NeedsLogin needsLogin = method.getAnnotation(NeedsLogin.class);
            if (needsLogin.required()) {
// 执行认证
                if (token == null) {
                    throw new BusinessException(ExceptionCode.EMPTY_TOKEN);
                }
// 获取 jwt 中的 phone
                String phone = null;
                try {
                    phone = JWTUtil.getTokenMessageBody(token);
                } catch (JWTDecodeException j) {
                    throw new
                            BusinessException(ExceptionCode.ADMIN_NO_MATCH);
                }
// 验证 token
                boolean verify = JWTUtil.verify(token, phone);
                if(!verify){
                    throw new BusinessException(ExceptionCode.WRONG_TOKEN);
                }
            }
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }

}
